/****************************************************************************
 *
 *  ALi (Shanghai) Corporation, All Rights Reserved. 2007 Copyright (C)
 *
 *  File: obj_animation.c
 *
 *  Description: animation object
 *
 *  History:
 *  Date            Author  		Version  Comment
 *  ====            ======  		=======  =======
 *  1.  2007.11.16   Sharon Zhang 	0.1.000  Initial
 *
 ****************************************************************************/
#include <sys_config.h>

#include <api/libc/string.h>
#include <api/libosd/osd_lib.h>
#include <api/libosd/osd_common_draw.h>
#include "osd_lib_internal.h"

#define PSEDO_ANIMATION_ID 1
//---------------------------- PRIVATE VARIABLES ----------------------------//
void Animation_Move2First(PANIMATION pCtrl)
{
	pCtrl->bCurFrameNum = 0;
}

UINT16 Animation_Move2Next(PANIMATION pCtrl)
{
	pCtrl->bCurFrameNum++;
	pCtrl->bCurFrameNum = (pCtrl->bCurFrameNum)%(pCtrl->bAllFrameNum);

	return (pCtrl->pFrame[pCtrl->bCurFrameNum]);
}

static void OSD_Animation_handler(UINT param_ani)
{
	PANIMATION pAni;

	pAni = (PANIMATION)param_ani;
	if((OSAL_INVALID_ID != pAni->TimerID)&&(TRUE == pAni->bMovingFlag))
	{
		pAni->anm_callback(OSD_ANM_REFRESH, param_ani);
	}
}

//---------------------------- PUBLIC FUNCTIONS -----------------------------//
/*void Animation_set_curFrame(PANIMATION pCtrl, UINT8 bCurFrame)
{
	pCtrl->bCurFrameNum = bCurFrame;
}
*/
void OSD_Animation_Start_Timer(PANIMATION pCtrl)
{
	OSAL_T_CTIM	t_dalm;

	if(pCtrl->head.bAttr != C_ATTR_ACTIVE)
		return;/*Invalid if inactive*/

	if(pCtrl->bMovingFlag != TRUE)
		return;

	if(OSD_GetTaskVscrBuffer(PSEDO_ANIMATION_ID) == NULL)
	{
		OSD_TaskBuffer_Init(PSEDO_ANIMATION_ID,NULL);
	}

	if((pCtrl->TimerID) != OSAL_INVALID_ID)
	{/*Delete old timer*/
		if(osal_timer_delete(pCtrl->TimerID) == E_OK)
			pCtrl->TimerID = OSAL_INVALID_ID;
	}
	
	t_dalm.callback = OSD_Animation_handler;
	t_dalm.type = OSAL_TIMER_CYCLE;
	t_dalm.time  = pCtrl->dwInterval;
	t_dalm.param = (UINT)(pCtrl);
	pCtrl->TimerID = osal_timer_create(&t_dalm);
	if(OSAL_INVALID_ID != pCtrl->TimerID)
	{
		osal_timer_activate(pCtrl->TimerID, 1);
	}
	else
	{
		return;
	}
}

void OSD_Animation_Stop_Timer(PANIMATION pCtrl)
{
	if((pCtrl->TimerID) != OSAL_INVALID_ID)
	{/*Delete timer*/
		if(osal_timer_delete(pCtrl->TimerID) == E_OK)
			pCtrl->TimerID = OSAL_INVALID_ID;
	}

}

void OSD_Animation_refresh(PANIMATION pCtrl)
{
	UINT16 icon_id;
	UINT32 vscr_idx;
	extern VSCR g_vscr[];

	if((OSAL_INVALID_ID != pCtrl->TimerID)&&(TRUE == pCtrl->bMovingFlag))
	{
		icon_id = Animation_Move2Next(pCtrl);
		OSD_DrawAnimationCell(pCtrl,pCtrl->head.style.bShowIdx,C_UPDATE_ALL);

		vscr_idx = osal_task_get_current_id();
		if((vscr_idx == OSAL_INVALID_ID) || (vscr_idx > OSD_DRAW_TASK_MAX))
			ASSERT(0);

		if(g_vscr[vscr_idx -1].lpbScr != NULL)
			g_vscr[vscr_idx -1].updatePending = 1;

		OSD_UpdateVscr(&g_vscr[vscr_idx - 1]);
	}
}

void OSD_DrawAnimationCell(PANIMATION pCtrl,UINT8 bStyleIdx,UINT32 nCmdDraw)
{
	lpVSCR  	pVscr;
	struct OSDRect	*objframe;	
	ID_RSC		RscId;
	PWINSTYLE  	lpWinSty;
	UINT32		fgColor;
	OBJECTINFO	RscLibInfo;
	UINT8 		bAlign,hAligin,vAlign;
	UINT16 		x,y,w,h;
	UINT16		wIconID;
	
	objframe	= &pCtrl->head.frame;	
	lpWinSty 	= g_osd_rsc_info.osd_get_win_style(bStyleIdx);
	fgColor		= lpWinSty->wFgIdx;
	RscId 		= LIB_ICON;
	bAlign 		= pCtrl->bAlign;
	
	pVscr = OSD_DrawObjectFrame(objframe,bStyleIdx);
	
	wIconID = pCtrl->pFrame[pCtrl->bCurFrameNum];
	
	if(wIconID)
	{
		
	    g_osd_rsc_info.osd_get_obj_info(RscId, wIconID, &RscLibInfo);
		w = RscLibInfo.m_objAttr.m_wActualWidth;
		h = RscLibInfo.m_objAttr.m_wHeight;
        hAligin = GET_HALIGN(bAlign);
        vAlign  = GET_VALIGN(bAlign);
		if(hAligin==C_ALIGN_LEFT)
			x = objframe->uLeft + pCtrl->bX;
		else if(hAligin==C_ALIGN_RIGHT)
			x = objframe->uLeft + objframe->uWidth - pCtrl->bX - w;
		else
		{
			if(w < (objframe->uWidth - (pCtrl->bX<<1) ) )
				x = objframe->uLeft + ((objframe->uWidth - w)>>1);
			else
				x = objframe->uLeft + pCtrl->bX;				
		}
		
		if(vAlign == C_ALIGN_TOP)
			y = objframe->uTop + pCtrl->bY;
		else if(vAlign == C_ALIGN_BOTTOM)
			y = objframe->uTop + objframe->uHeight - pCtrl->bY - h;
		else
		{
			if( h < (objframe->uHeight - (pCtrl->bY<<1) ) )
				y = objframe->uTop + ((objframe->uHeight - h)>>1);
			else
				y = objframe->uTop + pCtrl->bY;				
		}		
		
		g_osd_rsc_info.osd_get_obj_info(RscId,wIconID,&RscLibInfo);
			
		OSD_DrawPicture(x,y,wIconID,LIB_ICON,fgColor,pVscr);
	}

}

VACTION OSD_AnimationKeyMap(POBJECT_HEAD pObj, UINT32 vkey)
{
 	VACTION Action = VACT_PASS;

    switch(vkey)
    {
    case V_KEY_ENTER:
        Action = VACT_ENTER;
        break;
    default:
        break;
    }

    return Action;
}


PRESULT OSD_AnimationProc(POBJECT_HEAD pObj, UINT32 msg_type, UINT32 msg,UINT32 param1)
{
	PRESULT Result;

	if(msg_type == MSG_TYPE_KEY)
	{
		VACTION Action;
		UINT32 vkey;
		BOOL bContinue;    	

		Result = OSD_ObjCommonProc(pObj,msg,param1,&vkey,&Action,&bContinue);
		if(!bContinue)
			goto CHECK_LEAVE;

		switch(Action)
		{
			case VACT_CLOSE:
CLOSE_OBJECT:    		
				Result = OSD_ObjClose(pObj,C_CLOSE_CLRBACK_FLG);
				OSD_Animation_Stop_Timer((PANIMATION)pObj);/*Make sure it is closed,reserved here*/
				goto EXIT;
				break;
			default:
				Result = OSD_SIGNAL(pObj, EVN_UNKNOWN_ACTION, (Action<<16) | vkey, param1);
				break;
		}
	}
	else// if(msg_type==MSG_TYPE_EVNT)
	{
		if(msg_type == EVN_FOCUS_PRE_GET
			|| msg_type == EVN_PARENT_FOCUS_PRE_GET)
		{
			Animation_Move2First((PANIMATION)pObj);
			OSD_Animation_SetMoving((PANIMATION)pObj);
			OSD_Animation_Start_Timer((PANIMATION)pObj);
		}
		else if(msg_type == EVN_FOCUS_PRE_LOSE
			|| msg_type == EVN_PARENT_FOCUS_PRE_LOSE)
		{
			OSD_Animation_ClearMoving((PANIMATION)pObj);
			OSD_Animation_Stop_Timer((PANIMATION)pObj);
			Animation_Move2First((PANIMATION)pObj);
			OSD_DrawAnimationCell((PANIMATION)pObj,pObj->style.bShowIdx,C_UPDATE_ALL);
		}
		
		Result = OSD_SIGNAL(pObj,msg_type, msg, param1);
	}

CHECK_LEAVE:
	if(!(EVN_PRE_OPEN == msg_type))
		CHECK_LEAVE_RETURN(Result,pObj);

EXIT:
	return Result;		
}


